home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1993 July / InfoMagic USENET CD-ROM July 1993.ISO / sources / x / volume9 / acm / part04 < prev    next >
Encoding:
Internet Message Format  |  1990-10-09  |  52.7 KB

  1. Path: uunet!snorkelwacker!apple!netcom!amdcad!sun!mipsdal.mips.com
  2. From: riley@mipsdal.mips.com (Riley Rainey)
  3. Newsgroups: comp.sources.x
  4. Subject: v09i072: acm, X aerial combat simulation, Part04/05
  5. Message-ID: <143451@sun.Eng.Sun.COM>
  6. Date: 7 Oct 90 18:13:23 GMT
  7. References: <csx-09i069:acm@uunet.UU.NET>
  8. Sender: news@sun.Eng.Sun.COM
  9. Lines: 2041
  10. Approved: argv@sun.com
  11.  
  12. Submitted-by: riley@mipsdal.mips.com (Riley Rainey)
  13. Posting-number: Volume 9, Issue 72
  14. Archive-name: acm/part04
  15.  
  16. echo x - ./fsim/acm.1
  17. sed 's/^X//' >./fsim/acm.1 <<'*-*-END-of-./fsim/acm.1-*-*'
  18. X.TH ACM l "4 September 1990"
  19. X.SH NAME
  20. Xacm \- an aerial combat simulator for X
  21. X.SH SYNOPSIS
  22. X.B acm [ server ] [ options \]  
  23. X.LP
  24. X
  25. X.SH DESCRIPTION
  26. X
  27. Xacm is an air combat simulator that runs under the X window system.  Up to
  28. Xeight players can engage in simultaneous air combat.  Players fly jet aircraft
  29. Xequipped with radar, heat seeking missiles and cannon.
  30. X
  31. XThe program, "acm", calls a deamon already running on the specified
  32. Xserver_hostname and requests that your enter the game.  The shell variable
  33. X"ACMSERVER" optionally specifies the name of the server host.
  34. X
  35. XEach player flies something close to either an F-16C Falcon or MIG-23.
  36. X
  37. X
  38. X.SH USAGE REFERENCE
  39. X
  40. XTo begin play, the flight simulator server must be started manually on a
  41. Xsystem that is accessible to all players. 
  42. X
  43. XThe following command line will do that:
  44. X
  45. X.LP
  46. X.TP
  47. X    % acms
  48. X
  49. XThe following command line options are recognized by acm:
  50. X.LP
  51. X.TP
  52. X-geometry geometry_spec
  53. XAn X compatible window geometry specification
  54. X.TP
  55. X-team <1 or 2>
  56. XSpecifies the starting airfield.  Airfields are about 50 nm apart.
  57. XTeam 1 flies F-16's, team 2 flies MIG-23's.
  58. X
  59. X
  60. X.SH HOW TO TAKE-OFF
  61. X
  62. X
  63. XYour mouse is the control stick.  The neutral position is the center of your
  64. Xview display -- denoted by the dot in the center of your heads-up-display (HUD).
  65. XMoving the mouse away from you pitches the plane down, moving it back
  66. Xpitches the plane up.  Left and right inputs roll the aircraft in the
  67. Xcorresponding direction.  On the ground at speeds up to 100 kts, nose
  68. Xwheel steering guides the aircraft.
  69. X
  70. XTo take off for the first time, select 20 degrees of flaps (press H twice),
  71. Xthen press the full throttle key (the 4 key on the main keyboard).  Keep the
  72. Xmouse in the neutral position until you are moving at about 140 kts, then pull
  73. Xthe mouse about two-thirds of the way down the view window.  You should pitch
  74. Xup and lift off the ground fairly easily.  Gradually move the stick closer
  75. Xto the neutral position and let your airspeed build -- don't move it back to
  76. Xneutral too quickly or you will end up back on the ground again!  As your
  77. Xairspeed passes about 250 kts, raise the flaps (press Y twice). Congratulations,
  78. Xyou're flying a multi-million dollar jet.
  79. X
  80. X
  81. X.SH ENGINE CONTROLS
  82. X
  83. X
  84. XThe following keys control your engine thrust:
  85. X
  86. X.LP
  87. X    4    Full Power
  88. X.LP
  89. X    3    Increase Power (about 2 percent)
  90. X.LP
  91. X    2    Decrease Power (about the same amount)
  92. X.LP
  93. X    1    Idle Power
  94. X.LP
  95. X    A    Toggle Afterburner
  96. X
  97. XYour engine gauge displays the power that you are generating.  Below that,
  98. Xyou have displays showing your total fuel remaining as well as your current
  99. Xfuel consumption rate.  The afterburner uses fuel at an amazing rate; use it
  100. Xwisely.
  101. X
  102. X
  103. X.SH LOOKING AROUND
  104. X
  105. X
  106. XThe keys of the numeric keypad control which direction you're looking outside
  107. Xof the cockpit:
  108. X
  109. X.LP
  110. X        8 Forward
  111. X.LP    
  112. X    4 Left    5 Up    6 Right
  113. X.LP
  114. X        2 Aft
  115. X
  116. XIt pays to look around when you're in a combat environment.  Your chances
  117. Xof staying alive increase remarkably.
  118. X
  119. X
  120. X.SH THE HEADS UP DISPLAY (HUD)
  121. X
  122. X
  123. XOn the left side of the HUD is a ladder showing your current airspeed in
  124. Xnautical miles per hour (it displays true airspeed).  Above that, in the
  125. Xupper left corner, is a G-meter.  
  126. X
  127. XThe right ladder shows altitude; above that
  128. Xis a readout of your current angle-of-attack in degrees ("a=X.X").  
  129. XYour
  130. Xjet will stall at a 30 degrees positive angle of attack and negative 16 
  131. Xdegrees. 
  132. X
  133. XThe airplane symbol (something like "-O-") shows the direction
  134. Xthat the relative wind is coming from.  The relative wind combines your
  135. Xcurrent angles of attack and sideslip.  A ladder in the center of the
  136. XHUD show your aircraft's current attitude. 
  137. X
  138. XThe lower, horizontal ladder shows your current heading.  Discretes in the
  139. Xlower left-hand corner show the state of your weapons systems.  Slightly
  140. Xabove them is a readout of your current thrust percentage as well as the
  141. Xstate of your engine's afterburner -- the "AB" symbol means the
  142. Xafterburner is on.
  143. X
  144. X
  145. X.SH USING YOUR RADAR DISPLAY
  146. X
  147. X
  148. XThe radar system has a field of view of 130 degrees vertically and side-to-side.
  149. XRadar automatically locks onto the closest threat in its field of view.  A
  150. Xlocked target is displayed as a solid block.  Other hostile targets are 
  151. Xdisplayed as hollow squares.
  152. X
  153. XTargetting information is displayed in the lower right corner of the display.
  154. XThe top number is the heading of the locked target, the next number is the
  155. Xrelative heading you should steer to intercept the target (displayed as
  156. X"ddd R", and the third number is the rate that you are closing with this
  157. Xtarget, expressed in knots.
  158. X
  159. XYou can lock onto other targets by pressing the target designator key (Q).
  160. X
  161. X
  162. X.SH WHO'S GUNNING FOR ME?
  163. X
  164. X
  165. XRadar sets that are tracking your aircraft can be detected.  Your Threat
  166. XEarly Warning System (TEWS) display warns you of potential threats.  This
  167. Xcircular display shows the relative direction of radars (other aircraft)
  168. Xthat are looking at you.
  169. X
  170. X.SH ARMAMENTS
  171. X
  172. X
  173. XYour aircraft is equipped with heat-seeking missiles and a 20 millimeter
  174. Xcannon.  Weapon information is displayed in the lower left-hand corner of
  175. Xyour HUD.  Different weapons may be selected by pressing mouse button 3.
  176. X
  177. XThe missiles are patterned after U.S. AIM-9M Sidewinders.  They can
  178. Xdetect infared (IR) targets at any aspect (not just from the rear).  Their
  179. Xrange varies dramatically with the altitude and closure rate.  The
  180. Xmissile subsystem couples with your radar set to provide time-to-impact
  181. Xinformation when AIM-9's are selected.
  182. X
  183. X
  184. X.SH EXAMPLES
  185. X
  186. X acm bismarck 
  187. X
  188. X acm bismarck -geometry 1000x500
  189. X
  190. X.SH KEYBOARD COMMAND LIST
  191. X
  192. X
  193. X
  194. XEngine Controls
  195. X
  196. X.LP
  197. X4 -- Full Power
  198. X.LP
  199. X3 -- Increase Power
  200. X.LP
  201. X2 -- Decrease Power
  202. X.LP
  203. X1 -- Idle
  204. X.LP
  205. XA -- Toggle Afterburner State
  206. X
  207. X
  208. X
  209. XRadar Controls
  210. X
  211. X.LP
  212. XR -- Toggle Radar State (On/Standby)
  213. X.LP
  214. XQ -- Target Designator
  215. X
  216. X
  217. X
  218. XFlaps
  219. X
  220. X.LP
  221. XH -- Extend 10 degrees
  222. X.LP
  223. XY -- Retract 10 degrees
  224. X
  225. X
  226. X
  227. XSpeed Brakes
  228. X
  229. X.LP
  230. XS -- Extend
  231. X.LP
  232. XW -- Retract
  233. X
  234. X
  235. X
  236. XOther Controls
  237. X
  238. X.LP
  239. XP -- Self-Destruct (Quit the game)
  240. X.LP
  241. XL -- Launch a target drone
  242. X
  243. X
  244. X
  245. XView Controls (Numeric Keypad)
  246. X
  247. X.LP
  248. X8 -- Forward
  249. X.LP
  250. X2 -- Aft
  251. X.LP
  252. X4 -- Left
  253. X.LP
  254. X6 -- Right
  255. X.LP
  256. X5 -- Up
  257. X
  258. X
  259. X.SH NOTES FOR THE ADVANCED USER
  260. X
  261. XIf you turn your radar set to standby (the R key toggles your radar sets
  262. XON/STANDBY state), you don't emit radar signals, and, hence "disappear" from
  263. Xeveryone elses TEWS display.  It's harder to acquire targets visually, but it
  264. Xmay allow you to close in for the kill without alerting an opponent.
  265. X
  266. X
  267. X
  268. X.SH AUTHOR
  269. XRiley Rainey, riley@mips.com
  270. *-*-END-of-./fsim/acm.1-*-*
  271. echo x - ./fsim/manifest.h
  272. sed 's/^X//' >./fsim/manifest.h <<'*-*-END-of-./fsim/manifest.h-*-*'
  273. X/*
  274. X *  UPDATE_INTERVAL define the number of microseconds between
  275. X *  each position update when the game is running.
  276. X */
  277. X#define UPDATE_INTERVAL        125000
  278. X
  279. X/*
  280. X *  REDRAW_EVERY defines the number of update intervals between each
  281. X *  redraw of player screens.
  282. X */
  283. X
  284. X#define REDRAW_EVERY        4
  285. X
  286. X/*
  287. X *  ACM_PORT define the internet port number to be used in the game 
  288. X *  startup handshaking.
  289. X */
  290. X
  291. X#define ACM_PORT        3232
  292. X
  293. X/*
  294. X *  ACM becomes the name used to lookup X resources on a particular
  295. X *  X server.
  296. X */
  297. X
  298. X#define ACM            "acm"
  299. X
  300. X/*
  301. X *  Linear response to control stick inputs can make the plane harder
  302. X *  to fly.
  303. X */
  304. X
  305. X/* #define LINEAR_CONTROL_RESPONSE */
  306. *-*-END-of-./fsim/manifest.h-*-*
  307. echo x - ./fsim/newPlayer.c
  308. sed 's/^X//' >./fsim/newPlayer.c <<'*-*-END-of-./fsim/newPlayer.c-*-*'
  309. X/*
  310. X *    xflight : an aerial combat simulator for X
  311. X *
  312. X *    Written by Riley Rainey,  riley@mips.com
  313. X *
  314. X *    Permission to use, copy, modify and distribute (without charge) this
  315. X *    software, documentation, images, etc. is granted, provided that this 
  316. X *    comment and the author's name is retained.
  317. X *
  318. X */
  319. X#include "pm.h"
  320. X#include <stdio.h>
  321. X#include <X11/Xutil.h>
  322. X
  323. X#define BORDER    1
  324. X#define FONT            "*courier-bold-r-normal--17*"
  325. X#define    ARG_FONT        "font"
  326. X#define ARG_RADAR_FONT        "radarFont"
  327. X#define    ARG_BORDER_COLOR    "borderColor"
  328. X#define ARG_BORDER        "borderWidth"
  329. X#define    ARG_GEOMETRY        "geometry"
  330. X#define DEFAULT_BACKGROUND    "#93bde4"    /* my version of sky blue */
  331. X#define DEFAULT_BORDER        "black"
  332. X#define DEFAULT_RADAR_FONT    "fixed"
  333. X
  334. X#define SW_BORDER    1
  335. X#define SW_BACKGROUND    2
  336. X#define SW_HUDFONT    3
  337. X#define SW_GEOM        4
  338. X#define SW_RADARFONT    5
  339. X#define SW_TEAM        6
  340. X
  341. Xstruct {
  342. X    char    *sw;
  343. X    int    value;
  344. X    }    swt[] = {
  345. X    "-bw", SW_BORDER,
  346. X    "-skycolor", SW_BACKGROUND,
  347. X    "-hudfont",  SW_HUDFONT,
  348. X    "-radarfont",SW_RADARFONT,
  349. X    "-geometry", SW_GEOM,
  350. X    "-team",     SW_TEAM,
  351. X    NULL, 0}, *swp;
  352. X
  353. XXWMHints    xwmh = {
  354. X    (InputHint|StateHint),    /* flags */
  355. X    False,            /* input */
  356. X    NormalState,        /* initial_state */
  357. X    0,                /* icon pixmap */
  358. X    0,                /* icon window */
  359. X    0, 0,            /* icon location */
  360. X    0,                /* icon mask */
  361. X    0,                /* Window group */
  362. X};
  363. X
  364. Xvoid    recoverAcmArgv (args, argc, argv)
  365. Xchar    *args;
  366. Xint    *argc;
  367. Xchar    *argv[]; {
  368. X
  369. X    char *s;
  370. X
  371. X    argv[0] = ACM;
  372. X    argv[1] = args;
  373. X
  374. X    if (*args == '\0') {
  375. X        *argc = 1;
  376. X        argv[1] = (char *) NULL;
  377. X        return;
  378. X    }
  379. X    else
  380. X        *argc = 2;
  381. X
  382. X    for (s=args; *s;) {
  383. X        if (*s == '|') {
  384. X            *s = '\0';
  385. X            argv[(*argc)++] = ++s;
  386. X        }
  387. X        else
  388. X            ++s;
  389. X    }
  390. X
  391. X    argv[*argc] = (char *) NULL;
  392. X}
  393. X
  394. Xint    newPlayer(s, display, logname, switches)
  395. Xint    s;
  396. Xchar    *display;
  397. Xchar    *logname;
  398. Xchar    *switches; {
  399. X
  400. X    char       *fontName;    /* Name of font for string */
  401. X    XSizeHints    xsh;        /* Size hints for window manager */
  402. X    Colormap    cmap;
  403. X    GC        curGC;
  404. X    XGCValues    gcv;
  405. X    unsigned long pad;        /* Font size parameters */
  406. X    unsigned long bd;        /* Pixel values */
  407. X    unsigned long bw;        /* Border width */
  408. X    char       *tempstr;    /* Temporary string */
  409. X    XColor      color;        /* Temporary color */
  410. X    char       *geomSpec;    /* Window geometry string */
  411. X    XSetWindowAttributes xswa;    /* Temporary Set Window Attribute struct */
  412. X    char    **c;
  413. X    char    err[64];
  414. X    static char    *background = NULL;
  415. X    int        borderWidth = 1;
  416. X    int        i, player;
  417. X    int        width, height;
  418. X    viewer    *u;
  419. X    craft    *cf;
  420. X    double    scale;
  421. X    int        argc;
  422. X    char    *argv[32];
  423. X    int        screen, mono;
  424. X    char    *hudfont = NULL, *radarfont = NULL;
  425. X    int        team = 1;
  426. X    char    *plane;        /* name of plane type */
  427. X
  428. X    recoverAcmArgv (switches, &argc, argv);
  429. X
  430. X
  431. X    geomSpec = NULL;
  432. X    u = (viewer *) malloc (sizeof(viewer));
  433. X
  434. X/*
  435. X *  Parse command line
  436. X */
  437. X
  438. X    for (c = &argv[1]; *c != (char *) NULL; ++c)
  439. X    if (**c == '-') {
  440. X        for (swp = &swt[0]; swp->value != 0; ++swp)
  441. X        if (strcmp (swp->sw, *c) == 0) {
  442. X
  443. X            switch (swp->value) {
  444. X
  445. X            case SW_GEOM: 
  446. X                geomSpec = *(++c);
  447. X                break;
  448. X
  449. X            case SW_BORDER:
  450. X                borderWidth = atoi (*(++c));
  451. X                break;
  452. X
  453. X            case SW_BACKGROUND:
  454. X                background = *(++c);
  455. X                break;
  456. X
  457. X            case SW_HUDFONT:
  458. X                hudfont = *(++c);
  459. X                break;
  460. X
  461. X            case SW_RADARFONT:
  462. X                radarfont = *(++c);
  463. X                break;
  464. X
  465. X            case SW_TEAM:
  466. X                team = atoi (*(++c));
  467. X                break;
  468. X            }
  469. X                break;
  470. X        }
  471. X        if (swp->value == 0) {
  472. X        free ((char *) u);
  473. X        ptbl[player].type = CT_FREE;
  474. X        sprintf (err, "%s: invalid switch %s", ACM, *c);
  475. X        write (s, err, strlen(err));
  476. X        exit (1);
  477. X        }
  478. X    }
  479. X
  480. X    if (team == 1)
  481. X    plane = "f-16c";
  482. X    else
  483. X    plane = "mig-23";
  484. X
  485. X    if ((player = newPlane (plane)) < 0) {
  486. X    sprintf (err, "Sorry, acm is popular -- no room for \
  487. Xany more players at this moment.\n");
  488. X    write (s, err, strlen(err));
  489. X    return -1;
  490. X    }
  491. X
  492. X/*
  493. X *  assign a (kludged) team location.
  494. X */
  495. X
  496. X    if (team == 2) {
  497. X    ptbl[player].Sg.x = -0.6 * NM + 50.0;
  498. X    ptbl[player].Sg.y = 49.0 * NM;
  499. X    }
  500. X
  501. X    if ((u->dpy = XOpenDisplay(display)) == (Display *) NULL) {
  502. X    free ((char *) u);
  503. X    ptbl[player].type = CT_FREE;
  504. X    sprintf(err, "%s: can't open %s\n", ACM, display);
  505. X    write (s, err, strlen(err));
  506. X    return -1;
  507. X    }
  508. X    screen = DefaultScreen (u->dpy);
  509. X    mono = (DisplayPlanes (u->dpy, screen) == 1) ? 1 : 0;
  510. X
  511. X    if ((fontName = XGetDefault(u->dpy, ACM, ARG_FONT)) == NULL) {
  512. X    fontName = FONT;
  513. X    }
  514. X    if ((u->font = XLoadQueryFont(u->dpy, fontName)) == NULL) {
  515. X    XCloseDisplay (u->dpy);
  516. X    free ((char *) u);
  517. X    ptbl[player].type = CT_FREE;
  518. X    sprintf(err, "%s: display %s doesn't know font %s\n",
  519. X        ACM, display, fontName);
  520. X    write (s, err, strlen(err));
  521. X    return -1;
  522. X    }
  523. X    u->fth = u->font->max_bounds.ascent + u->font->max_bounds.descent;
  524. X    u->ftw = u->font->max_bounds.width;
  525. X
  526. X    if ((fontName = XGetDefault(u->dpy, ACM, ARG_RADAR_FONT)) == NULL) {
  527. X    fontName = DEFAULT_RADAR_FONT;
  528. X    }
  529. X    if ((u->rfont = XLoadQueryFont(u->dpy, fontName)) == NULL) {
  530. X    XCloseDisplay (u->dpy);
  531. X    free ((char *) u);
  532. X    ptbl[player].type = CT_FREE;
  533. X    sprintf(err, "%s: display %s doesn't know font %s\n",
  534. X        ACM, display, fontName);
  535. X    write (s, err, strlen(err));
  536. X    return -1;
  537. X    }
  538. X    u->rfth = u->rfont->max_bounds.ascent + u->rfont->max_bounds.descent;
  539. X    u->rftw = u->rfont->max_bounds.width;
  540. X
  541. X/*
  542. X * Select colors for the border, the window background, and the
  543. X * foreground.  We use the default colormap to allocate the colors in.
  544. X */
  545. X
  546. X    cmap = DefaultColormap(u->dpy, screen);
  547. X
  548. X    if (background == NULL)
  549. X    background = DEFAULT_BACKGROUND;
  550. X
  551. X    if ((tempstr = XGetDefault(u->dpy, ACM, ARG_BORDER_COLOR)) == NULL)
  552. X    tempstr = DEFAULT_BORDER;
  553. X    if (XParseColor(u->dpy, cmap, tempstr, &color) == 0) {
  554. X    XCloseDisplay (u->dpy);
  555. X    free ((char *) u);
  556. X    ptbl[player].type = CT_FREE;
  557. X    sprintf (err, "Can't get border color %s\n", tempstr);
  558. X    write (s, err, strlen(err));
  559. X    return -1;
  560. X    }
  561. X
  562. X    if (mono)
  563. X    bd = BlackPixel (u->dpy, screen);
  564. X    else {
  565. X        if (XAllocColor(u->dpy, cmap, &color) == 0) {
  566. X        XCloseDisplay (u->dpy);
  567. X        free ((char *) u);
  568. X        ptbl[player].type = CT_FREE;
  569. X        sprintf (err, "Cannot allocate color cells\n");
  570. X        write (s, err, strlen(err));
  571. X        return -1;
  572. X    }
  573. X    bd = color.pixel;
  574. X    }
  575. X
  576. X/*
  577. X * Set the border width of the window, and the gap between the text
  578. X * and the edge of the window, "pad".
  579. X */
  580. X
  581. X    pad = BORDER;
  582. X    if ((tempstr = XGetDefault(u->dpy, ACM, ARG_BORDER)) == NULL)
  583. X    bw = 1;
  584. X    else
  585. X    bw = atoi(tempstr);
  586. X
  587. X/*
  588. X * Deal with providing the window with an initial position & size.
  589. X * Fill out the XSizeHints struct to inform the window manager.
  590. X */
  591. X
  592. X    if (geomSpec == NULL)
  593. X        geomSpec = XGetDefault(u->dpy, ACM, ARG_GEOMETRY);
  594. X
  595. X/*
  596. X * If the defaults database doesn't contain a specification of the
  597. X * initial size & position - fit the window to the text and locate
  598. X * it in the center of the screen.
  599. X */
  600. X
  601. X    if (geomSpec == NULL) {
  602. X    xsh.flags = PPosition | PSize;
  603. X    xsh.height = FS_WINDOW_HEIGHT;
  604. X    xsh.width =  FS_WINDOW_WIDTH;
  605. X    xsh.x = (DisplayWidth(u->dpy, screen) - xsh.width) / 2;
  606. X    xsh.y = (DisplayHeight(u->dpy, screen) - xsh.height) / 2;
  607. X    }
  608. X    else {
  609. X    int         bitmask;
  610. X
  611. X    bzero((char *) &xsh, sizeof(xsh));
  612. X    bitmask = XGeometry(u->dpy, screen, geomSpec, geomSpec,
  613. X                bw, u->ftw, u->fth, pad, pad, &(xsh.x), &(xsh.y),
  614. X                &(xsh.width), &(xsh.height));
  615. X    if (bitmask & (XValue | YValue)) {
  616. X        xsh.flags |= USPosition;
  617. X    }
  618. X    if (bitmask & (WidthValue | HeightValue)) {
  619. X        xsh.flags |= USSize;
  620. X    }
  621. X    }
  622. X
  623. X/*
  624. X * Create the Window with the information in the XSizeHints, the
  625. X * border width,  and the border & background pixels.
  626. X */
  627. X
  628. X    u->win = XCreateSimpleWindow(u->dpy, DefaultRootWindow(u->dpy),
  629. X                  xsh.x, xsh.y, xsh.width, xsh.height,
  630. X                  bw, bd, 1);
  631. X
  632. X    scale = (double) xsh.width / (double) FS_WINDOW_WIDTH;
  633. X    width = xsh.width;
  634. X    height = xsh.height;
  635. X
  636. X/*
  637. X * Create a pixmap of the engine RPM gauge and flap indicators.
  638. X */
  639. X
  640. X    u->eng = XCreateBitmapFromData (u->dpy, u->win, eng_bits, eng_width,
  641. X    eng_height);
  642. X    u->flap[0] = XCreateBitmapFromData (u->dpy, u->win, flaps0_bits,
  643. X    flaps0_width, flaps0_height);
  644. X    u->flap[1] = XCreateBitmapFromData (u->dpy, u->win, flaps1_bits,
  645. X    flaps1_width, flaps1_height);
  646. X    u->flap[2] = XCreateBitmapFromData (u->dpy, u->win, flaps2_bits,
  647. X    flaps2_width, flaps2_height);
  648. X    u->flap[3] = XCreateBitmapFromData (u->dpy, u->win, flaps3_bits,
  649. X    flaps3_width, flaps3_height);
  650. X
  651. X/*
  652. X * Set the standard properties for the window managers.
  653. X */
  654. X
  655. X    XSetStandardProperties(u->dpy, u->win, ACM, ACM, None, argv, argc, &xsh);
  656. X    XSetWMHints(u->dpy, u->win, &xwmh);
  657. X
  658. X    xsh.width = RADAR_WINDOW_WIDTH * scale;
  659. X    xsh.height = RADAR_WINDOW_HEIGHT * scale;
  660. X    xsh.x = RADAR_X * scale;
  661. X    xsh.y = RADAR_Y * scale;
  662. X    u->rwin = XCreateWindow (u->dpy, u->win, xsh.x, xsh.y, xsh.width,
  663. X    xsh.height, 0, CopyFromParent, CopyFromParent, CopyFromParent,
  664. X    0, NULL);
  665. X
  666. X/*
  667. X * Ensure that the window's colormap field points to the default
  668. X * colormap,  so that the window manager knows the correct colormap to
  669. X * use for the window.  Also,  set the window's Bit
  670. X * Gravity to reduce Expose events.
  671. X */
  672. X
  673. X    xswa.colormap = DefaultColormap(u->dpy, screen);
  674. X    xswa.bit_gravity = NorthWestGravity;
  675. X    XChangeWindowAttributes(u->dpy, u->win, (CWColormap | CWBitGravity), &xswa);
  676. X
  677. X/*
  678. X * Create the GC for drawing the picture.
  679. X */
  680. X
  681. X    gcv.font = u->font->fid;
  682. X    curGC = XCreateGC(u->dpy, u->win, GCFont, &gcv);
  683. X    XSelectInput(u->dpy, u->win, KeyPressMask | ButtonPressMask |
  684. X    StructureNotifyMask | ButtonReleaseMask);
  685. X
  686. X/*
  687. X *  Fill-in the viewer structure
  688. X */
  689. X
  690. X    cf = &ptbl[player];
  691. X    cf->team = player;
  692. X    cf->vl = u;
  693. X    strncpy (cf->name, logname, sizeof (cf->name));
  694. X    strncpy (cf->display, display, sizeof (cf->display));
  695. X    u->next = (viewer *) NULL;
  696. X    u->width = VIEW_WINDOW_WIDTH * scale;
  697. X    u->height = VIEW_WINDOW_HEIGHT * scale;
  698. X    u->xCenter = u->width / 2;
  699. X    u->yCenter = u->height / 2;
  700. X
  701. X    u->radarWidth = RADAR_WINDOW_WIDTH * scale;
  702. X    u->radarHeight = RADAR_WINDOW_HEIGHT * scale;
  703. X    u->gc = curGC;
  704. X
  705. X    u->TEWSx = TEWS_X * scale;
  706. X    u->TEWSy = TEWS_Y * scale;
  707. X    u->TEWSSize = TEWS_SIZE * scale;
  708. X
  709. X    u->v = VOpenViewport (u->dpy, screen, u->win,
  710. X    12.0*25.4/1000.0, 0.5, scale * 0.70, u->width, u->height);
  711. X
  712. X    if (VBindColors (u->v, background) < 0) {
  713. X    XCloseDisplay (u->dpy);
  714. X    free ((char *) u);
  715. X    ptbl[player].type = CT_FREE;
  716. X    sprintf (err, "Error in binding colors.\n");
  717. X    write (s, err, strlen(err));
  718. X    return -1;
  719. X    }
  720. X
  721. X/*
  722. X *  Fill in the scale structures for the airspeed/altitude HUD scales.
  723. X */
  724. X
  725. X    u->altScale.xorg = ALT_ORG_X * scale;
  726. X    u->altScale.yorg = ALT_ORG_Y * scale;
  727. X    u->altScale.length = ALT_LENGTH * scale;
  728. X    u->altScale.orientation = ALT_ORIENT;
  729. X    u->altScale.scale = ALT_SCALE / scale;
  730. X    u->altScale.minorInterval = ALT_MIN_INTERVAL;
  731. X    u->altScale.minorSize = ALT_MIN_SIZE * scale;
  732. X    u->altScale.majorInterval = ALT_MAJ_INTERVAL;
  733. X    u->altScale.majorSize = ALT_MAJ_SIZE * scale;
  734. X    u->altScale.indexSize = ALT_INDEX_SIZE * scale;
  735. X    u->altScale.divisor = ALT_DIVISOR;
  736. X    u->altScale.format = ALT_FORMAT;
  737. X
  738. X    u->velScale.xorg = VEL_ORG_X * scale;
  739. X    u->velScale.yorg = VEL_ORG_Y * scale;
  740. X    u->velScale.length = VEL_LENGTH * scale;
  741. X    u->velScale.orientation = VEL_ORIENT;
  742. X    u->velScale.scale = VEL_SCALE / scale;
  743. X    u->velScale.minorInterval = VEL_MIN_INTERVAL;
  744. X    u->velScale.minorSize = VEL_MIN_SIZE * scale;
  745. X    u->velScale.majorInterval = VEL_MAJ_INTERVAL;
  746. X    u->velScale.majorSize = VEL_MAJ_SIZE * scale;
  747. X    u->velScale.indexSize = VEL_INDEX_SIZE * scale;
  748. X    u->velScale.divisor = VEL_DIVISOR;
  749. X    u->velScale.format = VEL_FORMAT;
  750. X
  751. X    u->hdgScale.xorg = HDG_ORG_X * scale;
  752. X    u->hdgScale.yorg = HDG_ORG_Y * scale;
  753. X    u->hdgScale.length = HDG_LENGTH * scale;
  754. X    u->hdgScale.orientation = HDG_ORIENT;
  755. X    u->hdgScale.scale = HDG_SCALE / scale;
  756. X    u->hdgScale.minorInterval = HDG_MIN_INTERVAL;
  757. X    u->hdgScale.minorSize = HDG_MIN_SIZE * scale;
  758. X    u->hdgScale.majorInterval = HDG_MAJ_INTERVAL;
  759. X    u->hdgScale.majorSize = HDG_MAJ_SIZE * scale;
  760. X    u->hdgScale.indexSize = HDG_INDEX_SIZE * scale;
  761. X    u->hdgScale.divisor = HDG_DIVISOR;
  762. X    u->hdgScale.format = HDG_FORMAT;
  763. X                                           
  764. X/*
  765. X * Map the window to make it visible.
  766. X */
  767. X
  768. X    XMapWindow(u->dpy, u->win);
  769. X    XMapWindow(u->dpy, u->rwin);
  770. X    VExposeBuffer (u->v, u->gc);
  771. X
  772. X    whitePixel = whiteColor->index;
  773. X    blackPixel = blackColor->index;
  774. X    HUDPixel = HUDColor->index;
  775. X
  776. X    return 0;
  777. X
  778. X}
  779. X
  780. Xint killPlayer (c)
  781. Xcraft    *c; {
  782. X
  783. X    viewer    *v, *vn;
  784. X    int    i;
  785. X
  786. X/*
  787. X *  Erase our radar emissions
  788. X */
  789. X
  790. X    for (i=0; i<MAXPLAYERS; ++i)
  791. X        ptbl[i].rval[c->index] = 0.0;
  792. X
  793. X/*
  794. X *  Free HUD string storage
  795. X */
  796. X
  797. X    if (c->leftHUD[0] != (char *) NULL)
  798. X        for (i=0; i<3; ++i) {
  799. X            free (c->leftHUD[i]);
  800. X            free (c->rightHUD[i]);
  801. X        }
  802. X
  803. X/*
  804. X *  Close viewers' display
  805. X */
  806. X
  807. X    for (v=c->vl; v != (viewer *) NULL;) {
  808. X        XCloseDisplay (v->dpy);
  809. X        vn = (viewer *) v->next;
  810. X        free ((char *) v);
  811. X        v = vn;
  812. X    }
  813. X
  814. X    if (c->flags && FL_RECORD)
  815. X        -- recordCount;
  816. X
  817. X    c->type = CT_FREE;
  818. X    return 0;
  819. X}
  820. *-*-END-of-./fsim/newPlayer.c-*-*
  821. echo x - ./fsim/missile.c
  822. sed 's/^X//' >./fsim/missile.c <<'*-*-END-of-./fsim/missile.c-*-*'
  823. X/*
  824. X *    xflight : an aerial combat simulator for X
  825. X *
  826. X *    Written by Riley Rainey,  riley@mips.com
  827. X *
  828. X *    Permission to use, copy, modify and distribute (without charge) this
  829. X *    software, documentation, images, etc. is granted, provided that this 
  830. X *    comment and the author's name is retained.
  831. X *
  832. X */
  833. X#include "pm.h"
  834. X#include <math.h>
  835. X
  836. Xtypedef struct _entry {
  837. X    double    time;
  838. X    double    min;
  839. X    craft    *c;
  840. X    struct    _entry *next;
  841. X    }    entry;
  842. X
  843. X
  844. Xextern craftType *lookupCraft();
  845. Xextern int mdebug;
  846. X
  847. Xint    fireMissile (c)
  848. Xcraft    *c; {
  849. X
  850. X    register craft    *m;
  851. X    register int    i;
  852. X    VPoint        s;
  853. X
  854. X    for ((i=0, m= &mtbl[0]); i<MAXPROJECTILES; (++i, ++m))
  855. X        if (m->type == CT_FREE) {
  856. X            m->type = CT_MISSILE;
  857. X            break;
  858. X        }
  859. X
  860. X    if (i == MAXPROJECTILES)
  861. X        return -1;
  862. X
  863. X    m->cinfo = lookupCraft ("aim-9m");
  864. X    m->fuel = m->cinfo->maxFuel;
  865. X    m->curThrust = m->cinfo->maxThrust;
  866. X    m->trihedral = c->trihedral;
  867. X    m->Itrihedral = c->Itrihedral;
  868. X    m->curRoll = c->curRoll;
  869. X    m->curPitch = c->curPitch;
  870. X    m->curHeading = c->curHeading;
  871. X    m->Cg = c->Cg;
  872. X    VTransform (&(c->cinfo->wStation[1]), &(c->trihedral), &s);
  873. X    m->Sg.x = c->Sg.x + s.x;
  874. X    m->Sg.y = c->Sg.y + s.y;
  875. X    m->Sg.z = c->Sg.z + s.z;
  876. X    m->armFuse = (int) (m->cinfo->armDelay / deltaT);
  877. X    m->flags = FL_HAS_GYRO;
  878. X
  879. X/*
  880. X * kludge
  881. X */
  882. X
  883. X    m->curRadarTarget = c->curRadarTarget;
  884. X
  885. X    return 0;
  886. X}
  887. X
  888. Xint    killMissile (c)
  889. Xcraft    *c; {
  890. X
  891. X    c->type = CT_FREE;
  892. X    return 0;
  893. X}
  894. X
  895. Xint    lookForImpacts () {
  896. X
  897. X    craft    *c, *m;
  898. X    entry    p[MAXPLAYERS], *list, *q, *r, *rprev;
  899. X    VPoint    v, s0;
  900. X    double    t, d;
  901. X    int    i, j;
  902. X
  903. X    for (m=mtbl, i=0; i<MAXPROJECTILES; ++i, ++m) {
  904. X
  905. X        if (m->type != CT_MISSILE || m->armFuse > 0)
  906. X            continue;
  907. X
  908. X        list = (entry *) NULL;
  909. X        for (c=ptbl, j=0; j<MAXPLAYERS; ++j, ++c) {
  910. X
  911. X            if (c->type == CT_FREE)
  912. X                continue;
  913. X
  914. X/*
  915. X * Reduce the relative motion of this object to a the parametric system
  916. X * of equations:
  917. X *        x(t) = vx * t + s0x
  918. X *        y(t) = vy * t + s0y
  919. X *        z(t) = vz * t + s0z
  920. X *
  921. X * We can then compute the time of perigee (closest pass) along with
  922. X * the associated minimum distance.
  923. X */
  924. X
  925. X            v.x = c->Sg.x - c->prevSg.x - m->Sg.x + m->prevSg.x;
  926. X            v.y = c->Sg.y - c->prevSg.y - m->Sg.y + m->prevSg.y;
  927. X            v.z = c->Sg.z - c->prevSg.z - m->Sg.z + m->prevSg.z;
  928. X            s0.x = c->prevSg.x - m->prevSg.x;
  929. X            s0.y = c->prevSg.y - m->prevSg.y;
  930. X            s0.z = c->prevSg.z - m->prevSg.z;
  931. X
  932. X/*
  933. X * Compute time of minimum distance between the two objects (note that units
  934. X * here are UPDATE_INTERVAL seconds).
  935. X */
  936. X
  937. X            t = - (v.x * s0.x + v.y * s0.y + v.z * s0.z) /
  938. X                (v.x * v.x + v.y * v.y + v.z * v.z);
  939. X
  940. X            if (mdebug)
  941. X            printf ("perigee in %g seconds with player %d\n", t*8.0, j);
  942. X
  943. X/*
  944. X *  If the closest pass occurs during this update interval, check for a hit.
  945. X *  We'll build a linked list of all craft that this projectile may strike
  946. X *  during this period, arranged in ascending order by time of "perigee"
  947. X *  (closest pass).  We'll then test for strikes.  If a projectile misses
  948. X *  the first object, then it may have struck subsequent objects in the
  949. X *  list ...
  950. X */
  951. X
  952. X/*
  953. X *  One special case occurs when a target or missile's turn suddenly
  954. X *  changes the perigee time from positive to negative.  If the missile
  955. X *  is within hitting range at t=0 and the time of perigee is negative,
  956. X *  then zap 'em.
  957. X */
  958. X
  959. X            if (t < 0.0) {
  960. X                d = sqrt (s0.x *s0.x + s0.y * s0.y +
  961. X                    s0.z * s0.z);
  962. X                if (isMissileHit (d, c)) {
  963. X                    printf ("detected a \"curve hit\"\n");
  964. X                    t = 0.0;
  965. X                }
  966. X            }
  967. X
  968. X            if (t >= 0.0 && t <= 1.0) {
  969. X                q = &p[i];
  970. X                if (list == (entry *) NULL) {
  971. X                    q->next = list;
  972. X                    list = q;
  973. X                }
  974. X                else if (list->time > t) {
  975. X                    q->next = list;
  976. X                    list = q;
  977. X                }
  978. X                else {
  979. X                    for (rprev=list, r=list->next; r != (entry *) NULL;) {
  980. X                        if (r->time > t) break;
  981. X                        rprev = r;
  982. X                        r = r->next;
  983. X                    }
  984. X                    if (rprev != list) 
  985. X                        rprev->next = q;
  986. X                    q->next = r;
  987. X                }
  988. X                q->time = t;
  989. X                q->c = c;
  990. X                q->min = sqrt (pow(v.x * t + s0.x, 2.0) +
  991. X                    pow (v.y * t + s0.y, 2.0) +
  992. X                    pow (v.z * t + s0.z, 2.0) );
  993. X                    if (mdebug)
  994. X                    printf ("perigee %g feet; craft %d.\n",
  995. X                        q->min, j);
  996. X            }
  997. X        }
  998. X
  999. X/*
  1000. X *  Now look for missile hits in the list of perigees.
  1001. X */
  1002. X
  1003. X        for (r=list; r != (entry *) NULL; r=r->next)
  1004. X            if (isMissileHit (r->min, r->c)) {
  1005. X                killMissile (m);
  1006. X                killPlayer (r->c);
  1007. X                break;
  1008. X            }
  1009. X    }
  1010. X}
  1011. X
  1012. Xint isMissileHit (min, c)
  1013. Xdouble min;
  1014. Xcraft    *c; {
  1015. X
  1016. X    return (min < 50.0) ? 1 : 0;
  1017. X}
  1018. X
  1019. X#define IRScanSlope     0.57735
  1020. X
  1021. Xint isIRVisible (c, m, t)
  1022. Xcraft *c;
  1023. XVMatrix *m;
  1024. XVPoint    *t; {
  1025. X
  1026. X    VPoint    relPos;
  1027. X
  1028. X    VTransform (&(c->Sg), m, t);
  1029. X
  1030. X    if (t->z < 0.0)
  1031. X        return 0;
  1032. X
  1033. X    relPos.x = t->x / (t->z * IRScanSlope);
  1034. X    relPos.y = t->y / (t->z * IRScanSlope);
  1035. X
  1036. X    return (sqrt(relPos.x*relPos.x + relPos.y*relPos.y) > 1.0) ? 0 : 1;
  1037. X}
  1038. X
  1039. Xint getIRTarget (c, m, t)
  1040. Xcraft *c;
  1041. XVMatrix *m;
  1042. XVPoint  *t; {
  1043. X
  1044. X    int    i, n;
  1045. X    craft    *p;
  1046. X    VPoint    tNew, tMin;
  1047. X    double    m1, min;
  1048. X
  1049. X    if (c->curRadarTarget != -1 && isIRVisible(&ptbl[c->curRadarTarget], m, t))
  1050. X        return c->curRadarTarget;
  1051. X
  1052. X/*
  1053. X *  Look for a target.  Designate the closest one as a new target.
  1054. X */
  1055. X
  1056. X    min = 1000000.0;
  1057. X    n = -1;
  1058. X    for (i=0, p=ptbl; i<MAXPLAYERS; ++i, ++p) {
  1059. X        if (p == c)
  1060. X            continue;
  1061. X        if (p->type != CT_FREE)
  1062. X        if (isIRVisible (p, m, &tNew)) {
  1063. X            m1 = mag(tNew);
  1064. X            if (m1 < min) {
  1065. X                n = i;
  1066. X                min = m1;
  1067. X                tMin = tNew;
  1068. X            }
  1069. X        }
  1070. X    }
  1071. X
  1072. X    *t = tMin;
  1073. X    return n;
  1074. X}
  1075. X
  1076. Xvoid createMissileEyeSpace (c, eyeSpace)
  1077. Xcraft    *c;
  1078. XVMatrix    *eyeSpace; {
  1079. X
  1080. X    VPoint    CntrInt, up, C1, C2;
  1081. X    VMatrix    mtx, es;
  1082. X    double    Hypotenuse, h1, SinA, CosA;
  1083. X
  1084. X/*
  1085. X *  Create an eyeSpace transformation matrix to convert from global to
  1086. X *  local coordinates.
  1087. X */
  1088. X
  1089. X    CntrInt.x = c->Sg.x + c->trihedral.m[0][0];
  1090. X    CntrInt.y = c->Sg.y + c->trihedral.m[1][0];
  1091. X    CntrInt.z = c->Sg.z + c->trihedral.m[2][0];
  1092. X
  1093. X/*
  1094. X *  If the missile has a gyroscope, then it can determine which way "down" is
  1095. X *  and, hence, compensate for gravity.  Here, we'll compensate by pointing
  1096. X *  the nose of the missile up by a maximum of 12 degrees at all times.
  1097. X */
  1098. X
  1099. X    if (c->flags & FL_HAS_GYRO)
  1100. X        if (c->curThrust > 0.0)
  1101. X            CntrInt.z += 0.208;
  1102. X        else
  1103. X            CntrInt.z += 0.30;
  1104. X
  1105. X    up.x = c->Sg.x - c->trihedral.m[0][2];
  1106. X    up.y = c->Sg.y - c->trihedral.m[1][2];
  1107. X    up.z = c->Sg.z - c->trihedral.m[2][2];
  1108. X
  1109. X    VIdentMatrix (eyeSpace);
  1110. X    eyeSpace->m[0][3] = -c->Sg.x;
  1111. X    eyeSpace->m[1][3] = -c->Sg.y;
  1112. X    eyeSpace->m[2][3] = -c->Sg.z;
  1113. X    VTransform(&CntrInt, eyeSpace, &C1);
  1114. X
  1115. X    VIdentMatrix (&mtx);
  1116. X    Hypotenuse = sqrt(C1.x * C1.x + C1.y * C1.y);
  1117. X    if (Hypotenuse > 0.0) {
  1118. X        CosA = C1.y / Hypotenuse;
  1119. X        SinA = C1.x / Hypotenuse;
  1120. X        mtx.m[0][0] = CosA;
  1121. X        mtx.m[1][0] = SinA;
  1122. X        mtx.m[0][1] = -SinA;
  1123. X        mtx.m[1][1] = CosA;
  1124. X        es = *eyeSpace;
  1125. X        VMatrixMult(&es, &mtx, eyeSpace);
  1126. X    }
  1127. X
  1128. X    VTransform(&CntrInt, eyeSpace, &C2);
  1129. X    VIdentMatrix (&mtx);
  1130. X    Hypotenuse = sqrt(C2.y * C2.y + C2.z * C2.z);
  1131. X    if (Hypotenuse > 0.0) {
  1132. X        CosA = C2.y / Hypotenuse;
  1133. X        SinA = -C2.z / Hypotenuse;
  1134. X        mtx.m[1][1] = CosA;
  1135. X        mtx.m[2][1] = SinA;
  1136. X        mtx.m[1][2] = -SinA;
  1137. X        mtx.m[2][2] = CosA;
  1138. X        es = *eyeSpace;
  1139. X        VMatrixMult(&es, &mtx, eyeSpace);
  1140. X    }
  1141. X
  1142. X        VTransform (&up, eyeSpace, &C2);
  1143. X    VIdentMatrix (&mtx);
  1144. X    h1 = sqrt (C2.y * C2.y + C2.z * C2.z);
  1145. X    Hypotenuse = sqrt(C2.x * C2.x + h1 * h1);
  1146. X    if (Hypotenuse > 0.0) {
  1147. X        CosA = h1 / Hypotenuse;
  1148. X        SinA = C2.x / Hypotenuse;
  1149. X        if (C2.z < 0.0) {
  1150. X            CosA = -CosA;
  1151. X        }
  1152. X        mtx.m[0][0] = CosA;
  1153. X        mtx.m[2][0] = SinA;
  1154. X        mtx.m[0][2] = -SinA;
  1155. X        mtx.m[2][2] = CosA;
  1156. X        es = *eyeSpace;
  1157. X        VMatrixMult(&es, &mtx, eyeSpace);
  1158. X    }
  1159. X
  1160. X    VIdentMatrix (&mtx);
  1161. X    mtx.m[1][1] = 0.0;
  1162. X    mtx.m[2][1] = 1.0;
  1163. X    mtx.m[1][2] = 1.0;
  1164. X    mtx.m[2][2] = 0.0;
  1165. X    es = *eyeSpace;
  1166. X    VMatrixMult(&es, &mtx, eyeSpace);
  1167. X
  1168. X}
  1169. X
  1170. Xvoid trackTarget (c)
  1171. Xcraft *c; {
  1172. X
  1173. X    VMatrix eyeSpace, mtx;
  1174. X    VPoint    t, t1;
  1175. X    double    v, h, m, maxTurnSlope, aMax = 30.0 * a;
  1176. X    double    deltaRoll, deltaPitch, deltaYaw;
  1177. X    double    cosR, sinR;
  1178. X
  1179. X    createMissileEyeSpace (c, &eyeSpace);
  1180. X
  1181. X/*
  1182. X *  Now let's get to target tracking;  first, if we don't already have a
  1183. X *  target designated, get one.
  1184. X */
  1185. X
  1186. X/*    if (c->armFuse > 0) {
  1187. X        t.x = 0.0;
  1188. X        t.y = 0.0;
  1189. X        t.z = 1.0;
  1190. X    }
  1191. X    else */if ((c->curRadarTarget = getIRTarget(c, &eyeSpace, &t)) == -1) {
  1192. X        if (mdebug)
  1193. X            printf ("Missile elects to self-destruct\n");
  1194. X        killMissile (c);
  1195. X        return;
  1196. X    }
  1197. X
  1198. X    t.x = t.x / t.z;
  1199. X    t.y = t.y / t.z;
  1200. X
  1201. X    h = sqrt (t.x*t.x + t.y*t.y);
  1202. X    v = mag (c->Cg);
  1203. X
  1204. X/*
  1205. X *  We'll constrain missile turns to a 20 degree/second unless it's velocity
  1206. X *  would make that greater than 30g's.
  1207. X */
  1208. X
  1209. X    if ((m=(v*v - aMax*aMax/4.0)) > 0.0)
  1210. X        maxTurnSlope = aMax / (2.0 * sqrt (m)) * deltaT;
  1211. X
  1212. X    else
  1213. X        maxTurnSlope = 0.3639 * deltaT;
  1214. X
  1215. X    if (mdebug)
  1216. X        printf ("slope = %g; maxTurnSlope = %g\n", h, maxTurnSlope);
  1217. X
  1218. X    if (h > maxTurnSlope) {
  1219. X        t.x = t.x * maxTurnSlope / h;
  1220. X        t.y = t.y * maxTurnSlope / h;
  1221. X    }
  1222. X
  1223. X        cosR = cos (c->curRoll);
  1224. X    sinR = sin (c->curRoll);
  1225. X
  1226. X    deltaRoll = 0.0;
  1227. X    deltaPitch = atan (t.y);
  1228. X    deltaYaw   = atan (t.x);
  1229. X
  1230. X/*
  1231. X *  Re-orient the velocity vector towards our new direction.
  1232. X */
  1233. X
  1234. X        VIdentMatrix (&mtx);
  1235. X    if (deltaPitch != 0.0)
  1236. X        VRotate (&mtx, YRotation, - deltaPitch);
  1237. X    if (deltaYaw != 0.0)
  1238. X        VRotate (&mtx, ZRotation, deltaYaw);
  1239. X    VTransform (&(c->Cg), &(c->Itrihedral), &t);
  1240. X    VTransform (&t, &mtx, &t1);
  1241. X    VTransform (&t1, &(c->trihedral), &(c->Cg));
  1242. X
  1243. X    if (mdebug)
  1244. X        printf ("Missile changes: pitch: %g, yaw: %g.\n",
  1245. X            RADtoDEG(deltaPitch), RADtoDEG(deltaYaw));
  1246. X
  1247. X    c->curRoll    += deltaRoll;
  1248. X    c->curHeading += sinR * deltaPitch + cosR * deltaYaw;
  1249. X    c->curPitch   += cosR * deltaPitch - sinR * deltaYaw;
  1250. X
  1251. X}
  1252. *-*-END-of-./fsim/missile.c-*-*
  1253. echo x - ./fsim/m61a1.c
  1254. sed 's/^X//' >./fsim/m61a1.c <<'*-*-END-of-./fsim/m61a1.c-*-*'
  1255. X/*
  1256. X *    xflight : an aerial combat simulator for X
  1257. X *
  1258. X *    Written by Riley Rainey,  riley@mips.com
  1259. X *
  1260. X *    Permission to use, copy, modify and distribute (without charge) this
  1261. X *    software, documentation, images, etc. is granted, provided that this 
  1262. X *    comment and the author's name is retained.
  1263. X *
  1264. X */
  1265. X#include "pm.h"
  1266. X#include <stdio.h>
  1267. X#include <string.h>
  1268. X#include <math.h>
  1269. X
  1270. X#define BORE_CROSS_SIZE    7
  1271. X#define MUZZLE_VELOCITY (3.2808 * 1036.0)
  1272. X#define TRACER_MOD    10    
  1273. X#define OFFSET_ANGLE    (DEGtoRAD(3.0))        /* the gun points up at this angle */
  1274. X#define RATE_OF_FIRE    (3000.0 / 60.0)        /* rounds per second */
  1275. X#define FUZZ        (DEGtoRAD(1.0))        /* distribution due to vibration */
  1276. X
  1277. Xint select_m61a1();
  1278. Xint display_m61a1();
  1279. Xint update_m61a1();
  1280. Xint press_m61a1();
  1281. Xint release_m61a1();
  1282. Xextern craftType * lookupCraft();
  1283. X
  1284. XweaponDesc m61a1Desc = {
  1285. X    WK_M61A1,
  1286. X    select_m61a1,        /* select */
  1287. X    update_m61a1,        /* update */
  1288. X    display_m61a1,        /* display procedure */
  1289. X    press_m61a1,        /* fire */
  1290. X    release_m61a1,        /* fire button release */
  1291. X    };
  1292. X
  1293. X/*
  1294. X *  m61a1 selection function
  1295. X *
  1296. X *  A selection function normally determines whether there are any weapons
  1297. X *  of this type on-board.  If so, and the weapon system is functional
  1298. X *  (in other words, undamaged) then return 1; otherwise return 0.
  1299. X */
  1300. X
  1301. Xint select_m61a1 (c)
  1302. Xcraft *c; {
  1303. X
  1304. X    if (c->station[0].type == WK_M61A1 && c->station[0].info > 0)
  1305. X        return 1;
  1306. X    else
  1307. X        return 0;
  1308. X
  1309. X}
  1310. X
  1311. X/*
  1312. X *  m61a1 display function
  1313. X *
  1314. X *  Update the HUD display strings associated with this weapon system.
  1315. X */
  1316. X
  1317. Xint display_m61a1 (c, w, u)
  1318. Xcraft *c;
  1319. XcraftType *w;
  1320. Xviewer *u; {
  1321. X
  1322. X    char    s[16];
  1323. X    register int tx, ty, m;
  1324. X    VPoint     tmp;
  1325. X    XSegment seg[2];
  1326. X
  1327. X    strcpy (c->leftHUD[0], "LCOS");
  1328. X    sprintf (s, "%.3d M-61A1", c->station[0].info);
  1329. X    strcpy (c->leftHUD[1], s);
  1330. X    if (c->station[0].info3)
  1331. X        strcpy (c->leftHUD[2], "FIRING");
  1332. X    else
  1333. X        strcpy (c->leftHUD[2], "");
  1334. X
  1335. X/*
  1336. X *  Draw the boresight cross
  1337. X */
  1338. X
  1339. X    m = (double) BORE_CROSS_SIZE * (double) u->width /
  1340. X        (double) VIEW_WINDOW_WIDTH + 0.5;
  1341. X
  1342. X    tx = u->xCenter;
  1343. X    ty = u->yCenter - 3 * 9;    /* kludged, for now */
  1344. X    seg[0].x1 = tx - m;
  1345. X    seg[0].x2 = tx + m;
  1346. X    seg[0].y1 = seg[0].y2 = ty;
  1347. X    seg[1].x1 = seg[1].x2 = tx;
  1348. X    seg[1].y1 = ty - m;
  1349. X    seg[1].y2 = ty + m;
  1350. X    XDrawSegments (u->dpy, u->win, u->gc, seg, 2);
  1351. X
  1352. X/*
  1353. X *  If we have a radar target designated, then draw a reticle.
  1354. X */
  1355. X/*
  1356. X    if (c->curRadarTarget >= 0) {
  1357. X        VTransform (&(ptbl[c->curRadarTarget].Sg),
  1358. X            &u->v->eyeSpace, &tmp);        
  1359. X        tx = u->v->Middl.x + tmp.x * u->v->Scale.x / tmp.z + 0.5;
  1360. X        ty = u->v->Middl.y - tmp.y * u->v->Scale.y / tmp.z + 0.5;
  1361. X    }
  1362. X*/
  1363. X}
  1364. X
  1365. Xint    press_m61a1 (c)
  1366. Xcraft    *c; {
  1367. X    c->station[0].info3 |= 1;
  1368. X    return 0;
  1369. X}
  1370. X
  1371. Xint    release_m61a1 (c)
  1372. Xcraft    *c; {
  1373. X    c->station[0].info3 &= ~1;
  1374. X    return 0;
  1375. X}
  1376. X
  1377. Xextern long random ();
  1378. X
  1379. Xint    update_m61a1 (c)
  1380. Xcraft    *c; {
  1381. X
  1382. X    craft    *m;
  1383. X    int    i;
  1384. X    VPoint    tmp, mvel;
  1385. X    int    rounds;
  1386. X    double    fuzz, fuzzAngle, phiY, phiZ, tm, mv = MUZZLE_VELOCITY;
  1387. X
  1388. X    if (c->station[0].info3 == 0)
  1389. X        return 0;
  1390. X
  1391. X/*
  1392. X *  Got any ammunition ?
  1393. X */
  1394. X
  1395. X    if (c->station[0].info <= 0)
  1396. X        return -1;
  1397. X
  1398. X/*
  1399. X *  Allocate a projectile record
  1400. X */
  1401. X
  1402. X    for ((i=0, m= &mtbl[0]); i<MAXPROJECTILES; (++i, ++m))
  1403. X        if (m->type == CT_FREE) {
  1404. X            m->type = CT_CANNON;
  1405. X            break;
  1406. X        }
  1407. X
  1408. X    if (i == MAXPROJECTILES)
  1409. X        return -1;
  1410. X
  1411. X/*
  1412. X *  Determine how far we're fuzzed off the ideal boresight.
  1413. X */
  1414. X
  1415. X    fuzz = ((double)(random() & 32767) +
  1416. X        (double)(random() & 32767)) / 32768.0 - 1.0;
  1417. X    fuzz = fuzz * FUZZ;
  1418. X    fuzzAngle = 2.0 * pi * (double)(random() & 511) / 512.0;
  1419. X
  1420. X/*
  1421. X *  Determine the initial velocity of the projectile stream.
  1422. X */
  1423. X
  1424. X    phiZ = fuzz * sin (fuzzAngle);
  1425. X    phiY = fuzz * cos (fuzzAngle);
  1426. X    tm = mv * cos (OFFSET_ANGLE + phiZ);
  1427. X
  1428. X    tmp.x = tm * cos (phiY); 
  1429. X    tmp.y = tm * sin (phiY); 
  1430. X    tmp.z = mv * sin (-OFFSET_ANGLE + phiZ);
  1431. X    VTransform (&tmp, &(c->trihedral), &mvel);
  1432. X
  1433. X    m->createTime = curTime;
  1434. X    m->Cg = c->Cg;
  1435. X    m->curRoll = c->curRoll;
  1436. X    m->curPitch = c->curPitch;
  1437. X    m->curHeading = c->curHeading;
  1438. X    m->Cg.x += mvel.x;
  1439. X    m->Cg.y += mvel.y;
  1440. X    m->Cg.z += mvel.z;
  1441. X
  1442. X/*
  1443. X *  Determine the initial position.
  1444. X */
  1445. X
  1446. X    VTransform (&(c->cinfo->wStation[0]), &(c->trihedral), &tmp);
  1447. X    m->Sg.x = c->Sg.x + tmp.x;
  1448. X    m->Sg.y = c->Sg.y + tmp.y;
  1449. X    m->Sg.z = c->Sg.z + tmp.z;
  1450. X
  1451. X/*
  1452. X *  Subtract the number of rounds fired.
  1453. X */
  1454. X
  1455. X    m->rounds = RATE_OF_FIRE * deltaT;
  1456. X    m->rounds = (m->rounds > c->station[0].info) ? c->station[0].info : m->rounds;
  1457. X    m->tracerMod = TRACER_MOD;
  1458. X    m->tracerVal = c->station[0].info2 % m->tracerMod;
  1459. X    c->station[0].info -= m->rounds;
  1460. X    c->station[0].info2 += m->rounds;
  1461. X
  1462. X    m->cinfo = lookupCraft ("m61a1 cannon");
  1463. X
  1464. X    return 0;
  1465. X
  1466. X}
  1467. X
  1468. Xextern craftType * newCraft ();
  1469. Xextern char * strdup();
  1470. X
  1471. Xint    placeCannon(c, m, poly, cnt)
  1472. Xcraft    *c;
  1473. XVMatrix    *m;
  1474. XVPolygon **poly;
  1475. Xint    *cnt; {
  1476. X
  1477. X    double    t, intervalT;
  1478. X    VPoint    v, s;
  1479. X    int    i, j, k, n;
  1480. X    VPoint     *q, tmp;
  1481. X    VPolygon **p;
  1482. X
  1483. X/*
  1484. X *  Reduce the shell path to a set of parametric equations.
  1485. X */
  1486. X
  1487. X    v.x = c->Sg.x - c->prevSg.x;
  1488. X    v.y = c->Sg.y - c->prevSg.y;
  1489. X    v.z = c->Sg.z - c->prevSg.z;
  1490. X
  1491. X/*
  1492. X *  Now add each tracer shell to the view.
  1493. X */
  1494. X
  1495. X    intervalT = 1.0 / c->rounds;
  1496. X    for (t=intervalT*c->tracerVal; t <= 1.0; t += intervalT * TRACER_MOD) {
  1497. X        s.x = -v.x * t;
  1498. X        s.y = -v.y * t;
  1499. X        s.z = -v.z * t;
  1500. X        if (c->Sg.z + s.z > 0.0)    /* underground? don't plot it */
  1501. X            continue;
  1502. X        n = c->cinfo->object->numPolys;
  1503. X        p = c->cinfo->object->polygon;
  1504. X        j = *cnt;
  1505. X        for (i=0; i<n; ++i) {
  1506. X            poly[j] = VCopyPolygon(p[i]);
  1507. X            for ((k=0, q=poly[j]->vertex); k<poly[j]->numVtces; (++k, ++q)) {
  1508. X                VTransform(q, m, &tmp);
  1509. X                tmp.x += s.x;
  1510. X                tmp.y += s.y;
  1511. X                tmp.z += s.z;
  1512. X                *q = tmp;
  1513. X            }
  1514. X            ++j;
  1515. X        }
  1516. X        *cnt = j;
  1517. X    }
  1518. X
  1519. X}
  1520. X
  1521. Xvoid initm61a1()
  1522. X{
  1523. X
  1524. X    craftType    *c;
  1525. X    FILE        *f;
  1526. X
  1527. X    wtbl[1] = m61a1Desc;
  1528. X
  1529. X    c = newCraft();
  1530. X    c->name = strdup("m61a1 cannon");
  1531. X
  1532. X    c->placeProc = placeCannon;
  1533. X
  1534. X    f = fopen ("bullet", "r");
  1535. X    c->object = VReadObject(f);
  1536. X    fclose (f);
  1537. X
  1538. X}
  1539. X
  1540. Xint cannonCalculations (c)
  1541. Xcraft *c; {
  1542. X
  1543. X
  1544. X/*
  1545. X *  Kill projectile streams after 10.0 seconds of flight or when
  1546. X *  they strike the ground.
  1547. X */
  1548. X
  1549. X    if (curTime - c->createTime > 10.0)
  1550. X        return 1;
  1551. X
  1552. X    if (c->Sg.z > 0.0)
  1553. X        return 1;
  1554. X
  1555. X    c->prevSg = c->Sg;
  1556. X
  1557. X    c->Sg.x += c->Cg.x * deltaT;
  1558. X    c->Sg.y += c->Cg.y * deltaT;
  1559. X    c->Sg.z += c->Cg.z * deltaT + a * halfDeltaTSquared;
  1560. X
  1561. X    c->Cg.z += a * deltaT;
  1562. X    return 0;
  1563. X
  1564. X}
  1565. *-*-END-of-./fsim/m61a1.c-*-*
  1566. echo x - ./fsim/README
  1567. sed 's/^X//' >./fsim/README <<'*-*-END-of-./fsim/README-*-*'
  1568. Xacm Flight Simulator version 1.0
  1569. X
  1570. XThis software is divided into two major parts: the 3-D graphics routines
  1571. Xand the flight simulator itself.  The 3-D stuff is contained in the V
  1572. Xdirectory.  V/lib holds the library itself along with imake and make files.
  1573. XV/test contains a program that can be used to test your port of the
  1574. XV library.
  1575. X
  1576. XFsim contains the remainder of the flight simulator.  A makefile for
  1577. XMips RISC/os is provided.  The code has a Berkeley tilt to it in many
  1578. Xplaces, so people with hybrid OS's will probably want to lean that
  1579. Xdirection when selecting compiling and linking options.
  1580. X
  1581. XThe acm server, acms, must currently be started manually.  It's intended
  1582. Xthat it will eventually be managed automatically by inetd, but that's
  1583. Xnot in the code yet.  I have access to a network that includes a 16+ SPECMark
  1584. Xserver and 12 to 18 SPECMark workstations (i.e. a MIPS 3260 along with
  1585. XMIPS 2030 and Magnum workstations) (translate SPECMarks into millions of
  1586. Xinstructions per second by whatever formula you like ..).  I generally 
  1587. Xrlogin to the 3260 and start the acms process on it and leave that xterm
  1588. Xwindow hanging around;  then, from another xterm window, I'll fire off
  1589. Xthe acm command that starts my flying session.  Other players enter the
  1590. Xgame by simply firing off an "acm servername" command.
  1591. X
  1592. XI'm not saying that acm is a particularly accurate flight simulator. I'm
  1593. Xnot an aero engineer, but I did spend a fair amount of time studying
  1594. Xseveral college-level texts on the subject while I was designing this
  1595. Xsoftware.  This probably doesn't resemble real-time flight simulators
  1596. Xtoo much but, again, that's not my line of work.  Comments and
  1597. Xsuggestions to improve this software are welcome.
  1598. X
  1599. XSeveral "features" in this revision of the software:
  1600. X
  1601. X    * landing gear is ignored.  Raise it, lower it; it's
  1602. X      not handled by the software.
  1603. X
  1604. X    * flaps can be lowered at rediculously high speeds.
  1605. X
  1606. X    * cannon fire will not hit other aircraft.  Missiles
  1607. X      sure will, though.
  1608. X
  1609. X    * you can fly through mountains.
  1610. X
  1611. X    * engines do not flame-out.  Fly really high (and fast enough)
  1612. X      and you can just about get into orbit.  Non-afterburning
  1613. X      engine performance does degrade as altitude increases, but
  1614. X      afterburner performance gives the extra kick needed to fly
  1615. X      much higher than you should be able to.
  1616. X
  1617. X    * A hit kills you instantly.  acm does not currently have a
  1618. X      notion of limited aircraft damage.  It may in the future.
  1619. X
  1620. X
  1621. XRiley Rainey
  1622. XOctober 1, 1990
  1623. *-*-END-of-./fsim/README-*-*
  1624. echo x - ./fsim/update.c
  1625. sed 's/^X//' >./fsim/update.c <<'*-*-END-of-./fsim/update.c-*-*'
  1626. X/*
  1627. X *    xflight : an aerial combat simulator for X
  1628. X *
  1629. X *    Written by Riley Rainey,  riley@mips.com
  1630. X *
  1631. X *    Permission to use, copy, modify and distribute (without charge) this
  1632. X *    software, documentation, images, etc. is granted, provided that this 
  1633. X *    comment and the author's name is retained.
  1634. X *
  1635. X */
  1636. X#include "pm.h"
  1637. X#include <X11/Xutil.h>
  1638. X
  1639. Xextern int flightCalculations();
  1640. Xextern int missileCalculations();
  1641. Xextern void doEvents(), doViews(), flapControl();
  1642. X
  1643. Xint cur = 0;
  1644. X
  1645. Xint redraw () {
  1646. X
  1647. X    int    i, j;
  1648. X    craft    *p;
  1649. X    
  1650. X    for ((i=0, p=ptbl); i<MAXPLAYERS; (++i, ++p)) {
  1651. X        if (p->type == CT_PLANE) {
  1652. X            doEvents (p);
  1653. X            if (flightCalculations (p) == 1)
  1654. X                killPlayer (p);
  1655. X            doWeaponUpdate (p);
  1656. X            flapControl (p);
  1657. X        }
  1658. X        else if (p->type == CT_DRONE)
  1659. X            if (droneCalculations (p) == 1)
  1660. X                killPlayer (p);
  1661. X    }
  1662. X
  1663. X    for ((i=0, p=mtbl); i<MAXPROJECTILES; (++i, ++p)) {
  1664. X        if (p->type == CT_MISSILE) {
  1665. X            if (missileCalculations (p) == 1)
  1666. X                killMissile (p);
  1667. X        }
  1668. X        else if (p->type == CT_CANNON)
  1669. X            if (cannonCalculations (p) == 1)
  1670. X                killMissile (p);
  1671. X    }
  1672. X
  1673. X    lookForImpacts ();
  1674. X
  1675. X    if (cur++ % REDRAW_EVERY == 0)
  1676. X        doViews ();
  1677. X
  1678. X    curTime += deltaT;
  1679. X
  1680. X    return 0;
  1681. X
  1682. X}
  1683. *-*-END-of-./fsim/update.c-*-*
  1684. echo x - ./fsim/rwy.old
  1685. sed 's/^X//' >./fsim/rwy.old <<'*-*-END-of-./fsim/rwy.old-*-*'
  1686. XRunway
  1687. X280 69
  1688. X1 0.000000 -75.000000 0.000000
  1689. X2 12000.000000 -75.000000 0.000000
  1690. X3 12000.000000 75.000000 0.000000
  1691. X4 0.000000 75.000000 0.000000
  1692. X5 0.000000 -75.000000 0.000000
  1693. X6 12000.000000 -75.000000 0.000000
  1694. X7 12000.000000 -70.000000 0.000000
  1695. X8 0.000000 -70.000000 0.000000
  1696. X9 0.000000 75.000000 0.000000
  1697. X10 12000.000000 75.000000 0.000000
  1698. X11 12000.000000 70.000000 0.000000
  1699. X12 0.000000 70.000000 0.000000
  1700. X13 1000.000000 -66.000000 0.000000
  1701. X14 1125.000000 -66.000000 0.000000
  1702. X15 1125.000000 -36.000000 0.000000
  1703. X16 1000.000000 -36.000000 0.000000
  1704. X17 1000.000000 66.000000 0.000000
  1705. X18 1125.000000 66.000000 0.000000
  1706. X19 1125.000000 36.000000 0.000000
  1707. X20 1000.000000 36.000000 0.000000
  1708. X21 11000.000000 -66.000000 0.000000
  1709. X22 10875.000000 -66.000000 0.000000
  1710. X23 10875.000000 -36.000000 0.000000
  1711. X24 11000.000000 -36.000000 0.000000
  1712. X25 11000.000000 66.000000 0.000000
  1713. X26 10875.000000 66.000000 0.000000
  1714. X27 10875.000000 36.000000 0.000000
  1715. X28 11000.000000 36.000000 0.000000
  1716. X29 4.000000 -66.000000 0.000000
  1717. X30 129.000000 -66.000000 0.000000
  1718. X31 129.000000 -54.888889 0.000000
  1719. X32 4.000000 -54.888889 0.000000
  1720. X33 4.000000 -50.888889 0.000000
  1721. X34 129.000000 -50.888889 0.000000
  1722. X35 129.000000 -39.777779 0.000000
  1723. X36 4.000000 -39.777779 0.000000
  1724. X37 4.000000 -35.777779 0.000000
  1725. X38 129.000000 -35.777779 0.000000
  1726. X39 129.000000 -24.666666 0.000000
  1727. X40 4.000000 -24.666666 0.000000
  1728. X41 4.000000 -20.666666 0.000000
  1729. X42 129.000000 -20.666666 0.000000
  1730. X43 129.000000 -9.555555 0.000000
  1731. X44 4.000000 -9.555555 0.000000
  1732. X45 4.000000 9.555555 0.000000
  1733. X46 129.000000 9.555555 0.000000
  1734. X47 129.000000 20.666666 0.000000
  1735. X48 4.000000 20.666666 0.000000
  1736. X49 4.000000 24.666666 0.000000
  1737. X50 129.000000 24.666666 0.000000
  1738. X51 129.000000 35.777779 0.000000
  1739. X52 4.000000 35.777779 0.000000
  1740. X53 4.000000 39.777779 0.000000
  1741. X54 129.000000 39.777779 0.000000
  1742. X55 129.000000 50.888889 0.000000
  1743. X56 4.000000 50.888889 0.000000
  1744. X57 4.000000 54.888889 0.000000
  1745. X58 129.000000 54.888889 0.000000
  1746. X59 129.000000 66.000000 0.000000
  1747. X60 4.000000 66.000000 0.000000
  1748. X61 11996.000000 -66.000000 0.000000
  1749. X62 11871.000000 -66.000000 0.000000
  1750. X63 11871.000000 -54.888889 0.000000
  1751. X64 11996.000000 -54.888889 0.000000
  1752. X65 11996.000000 -50.888889 0.000000
  1753. X66 11871.000000 -50.888889 0.000000
  1754. X67 11871.000000 -39.777779 0.000000
  1755. X68 11996.000000 -39.777779 0.000000
  1756. X69 11996.000000 -35.777779 0.000000
  1757. X70 11871.000000 -35.777779 0.000000
  1758. X71 11871.000000 -24.666666 0.000000
  1759. X72 11996.000000 -24.666666 0.000000
  1760. X73 11996.000000 -20.666666 0.000000
  1761. X74 11871.000000 -20.666666 0.000000
  1762. X75 11871.000000 -9.555555 0.000000
  1763. X76 11996.000000 -9.555555 0.000000
  1764. X77 11996.000000 9.555555 0.000000
  1765. X78 11871.000000 9.555555 0.000000
  1766. X79 11871.000000 20.666666 0.000000
  1767. X80 11996.000000 20.666666 0.000000
  1768. X81 11996.000000 24.666666 0.000000
  1769. X82 11871.000000 24.666666 0.000000
  1770. X83 11871.000000 35.777779 0.000000
  1771. X84 11996.000000 35.777779 0.000000
  1772. X85 11996.000000 39.777779 0.000000
  1773. X86 11871.000000 39.777779 0.000000
  1774. X87 11871.000000 50.888889 0.000000
  1775. X88 11996.000000 50.888889 0.000000
  1776. X89 11996.000000 54.888889 0.000000
  1777. X90 11871.000000 54.888889 0.000000
  1778. X91 11871.000000 66.000000 0.000000
  1779. X92 11996.000000 66.000000 0.000000
  1780. X93 258.000000 -2.500000 0.000000
  1781. X94 383.000000 -2.500000 0.000000
  1782. X95 383.000000 2.500000 0.000000
  1783. X96 258.000000 2.500000 0.000000
  1784. X97 508.000000 -2.500000 0.000000
  1785. X98 633.000000 -2.500000 0.000000
  1786. X99 633.000000 2.500000 0.000000
  1787. X100 508.000000 2.500000 0.000000
  1788. X101 758.000000 -2.500000 0.000000
  1789. X102 883.000000 -2.500000 0.000000
  1790. X103 883.000000 2.500000 0.000000
  1791. X104 758.000000 2.500000 0.000000
  1792. X105 1008.000000 -2.500000 0.000000
  1793. X106 1133.000000 -2.500000 0.000000
  1794. X107 1133.000000 2.500000 0.000000
  1795. X108 1008.000000 2.500000 0.000000
  1796. X109 1258.000000 -2.500000 0.000000
  1797. X110 1383.000000 -2.500000 0.000000
  1798. X111 1383.000000 2.500000 0.000000
  1799. X112 1258.000000 2.500000 0.000000
  1800. X113 1508.000000 -2.500000 0.000000
  1801. X114 1633.000000 -2.500000 0.000000
  1802. X115 1633.000000 2.500000 0.000000
  1803. X116 1508.000000 2.500000 0.000000
  1804. X117 1758.000000 -2.500000 0.000000
  1805. X118 1883.000000 -2.500000 0.000000
  1806. X119 1883.000000 2.500000 0.000000
  1807. X120 1758.000000 2.500000 0.000000
  1808. X121 2008.000000 -2.500000 0.000000
  1809. X122 2133.000000 -2.500000 0.000000
  1810. X123 2133.000000 2.500000 0.000000
  1811. X124 2008.000000 2.500000 0.000000
  1812. X125 2258.000000 -2.500000 0.000000
  1813. X126 2383.000000 -2.500000 0.000000
  1814. X127 2383.000000 2.500000 0.000000
  1815. X128 2258.000000 2.500000 0.000000
  1816. X129 2508.000000 -2.500000 0.000000
  1817. X130 2633.000000 -2.500000 0.000000
  1818. X131 2633.000000 2.500000 0.000000
  1819. X132 2508.000000 2.500000 0.000000
  1820. X133 2758.000000 -2.500000 0.000000
  1821. X134 2883.000000 -2.500000 0.000000
  1822. X135 2883.000000 2.500000 0.000000
  1823. X136 2758.000000 2.500000 0.000000
  1824. X137 3008.000000 -2.500000 0.000000
  1825. X138 3133.000000 -2.500000 0.000000
  1826. X139 3133.000000 2.500000 0.000000
  1827. X140 3008.000000 2.500000 0.000000
  1828. X141 3258.000000 -2.500000 0.000000
  1829. X142 3383.000000 -2.500000 0.000000
  1830. X143 3383.000000 2.500000 0.000000
  1831. X144 3258.000000 2.500000 0.000000
  1832. X145 3508.000000 -2.500000 0.000000
  1833. X146 3633.000000 -2.500000 0.000000
  1834. X147 3633.000000 2.500000 0.000000
  1835. X148 3508.000000 2.500000 0.000000
  1836. X149 3758.000000 -2.500000 0.000000
  1837. X150 3883.000000 -2.500000 0.000000
  1838. X151 3883.000000 2.500000 0.000000
  1839. X152 3758.000000 2.500000 0.000000
  1840. X153 4008.000000 -2.500000 0.000000
  1841. X154 4133.000000 -2.500000 0.000000
  1842. X155 4133.000000 2.500000 0.000000
  1843. X156 4008.000000 2.500000 0.000000
  1844. X157 4258.000000 -2.500000 0.000000
  1845. X158 4383.000000 -2.500000 0.000000
  1846. X159 4383.000000 2.500000 0.000000
  1847. X160 4258.000000 2.500000 0.000000
  1848. X161 4508.000000 -2.500000 0.000000
  1849. X162 4633.000000 -2.500000 0.000000
  1850. X163 4633.000000 2.500000 0.000000
  1851. X164 4508.000000 2.500000 0.000000
  1852. X165 4758.000000 -2.500000 0.000000
  1853. X166 4883.000000 -2.500000 0.000000
  1854. X167 4883.000000 2.500000 0.000000
  1855. X168 4758.000000 2.500000 0.000000
  1856. X169 5008.000000 -2.500000 0.000000
  1857. X170 5133.000000 -2.500000 0.000000
  1858. X171 5133.000000 2.500000 0.000000
  1859. X172 5008.000000 2.500000 0.000000
  1860. X173 5258.000000 -2.500000 0.000000
  1861. X174 5383.000000 -2.500000 0.000000
  1862. X175 5383.000000 2.500000 0.000000
  1863. X176 5258.000000 2.500000 0.000000
  1864. X177 5508.000000 -2.500000 0.000000
  1865. X178 5633.000000 -2.500000 0.000000
  1866. X179 5633.000000 2.500000 0.000000
  1867. X180 5508.000000 2.500000 0.000000
  1868. X181 5758.000000 -2.500000 0.000000
  1869. X182 5883.000000 -2.500000 0.000000
  1870. X183 5883.000000 2.500000 0.000000
  1871. X184 5758.000000 2.500000 0.000000
  1872. X185 6008.000000 -2.500000 0.000000
  1873. X186 6133.000000 -2.500000 0.000000
  1874. X187 6133.000000 2.500000 0.000000
  1875. X188 6008.000000 2.500000 0.000000
  1876. X189 6258.000000 -2.500000 0.000000
  1877. X190 6383.000000 -2.500000 0.000000
  1878. X191 6383.000000 2.500000 0.000000
  1879. X192 6258.000000 2.500000 0.000000
  1880. X193 6508.000000 -2.500000 0.000000
  1881. X194 6633.000000 -2.500000 0.000000
  1882. X195 6633.000000 2.500000 0.000000
  1883. X196 6508.000000 2.500000 0.000000
  1884. X197 6758.000000 -2.500000 0.000000
  1885. X198 6883.000000 -2.500000 0.000000
  1886. X199 6883.000000 2.500000 0.000000
  1887. X200 6758.000000 2.500000 0.000000
  1888. X201 7008.000000 -2.500000 0.000000
  1889. X202 7133.000000 -2.500000 0.000000
  1890. X203 7133.000000 2.500000 0.000000
  1891. X204 7008.000000 2.500000 0.000000
  1892. X205 7258.000000 -2.500000 0.000000
  1893. X206 7383.000000 -2.500000 0.000000
  1894. X207 7383.000000 2.500000 0.000000
  1895. X208 7258.000000 2.500000 0.000000
  1896. X209 7508.000000 -2.500000 0.000000
  1897. X210 7633.000000 -2.500000 0.000000
  1898. X211 7633.000000 2.500000 0.000000
  1899. X212 7508.000000 2.500000 0.000000
  1900. X213 7758.000000 -2.500000 0.000000
  1901. X214 7883.000000 -2.500000 0.000000
  1902. X215 7883.000000 2.500000 0.000000
  1903. X216 7758.000000 2.500000 0.000000
  1904. X217 8008.000000 -2.500000 0.000000
  1905. X218 8133.000000 -2.500000 0.000000
  1906. X219 8133.000000 2.500000 0.000000
  1907. X220 8008.000000 2.500000 0.000000
  1908. X221 8258.000000 -2.500000 0.000000
  1909. X222 8383.000000 -2.500000 0.000000
  1910. X223 8383.000000 2.500000 0.000000
  1911. X224 8258.000000 2.500000 0.000000
  1912. X225 8508.000000 -2.500000 0.000000
  1913. X226 8633.000000 -2.500000 0.000000
  1914. X227 8633.000000 2.500000 0.000000
  1915. X228 8508.000000 2.500000 0.000000
  1916. X229 8758.000000 -2.500000 0.000000
  1917. X230 8883.000000 -2.500000 0.000000
  1918. X231 8883.000000 2.500000 0.000000
  1919. X232 8758.000000 2.500000 0.000000
  1920. X233 9008.000000 -2.500000 0.000000
  1921. X234 9133.000000 -2.500000 0.000000
  1922. X235 9133.000000 2.500000 0.000000
  1923. X236 9008.000000 2.500000 0.000000
  1924. X237 9258.000000 -2.500000 0.000000
  1925. X238 9383.000000 -2.500000 0.000000
  1926. X239 9383.000000 2.500000 0.000000
  1927. X240 9258.000000 2.500000 0.000000
  1928. X241 9508.000000 -2.500000 0.000000
  1929. X242 9633.000000 -2.500000 0.000000
  1930. X243 9633.000000 2.500000 0.000000
  1931. X244 9508.000000 2.500000 0.000000
  1932. X245 9758.000000 -2.500000 0.000000
  1933. X246 9883.000000 -2.500000 0.000000
  1934. X247 9883.000000 2.500000 0.000000
  1935. X248 9758.000000 2.500000 0.000000
  1936. X249 10008.000000 -2.500000 0.000000
  1937. X250 10133.000000 -2.500000 0.000000
  1938. X251 10133.000000 2.500000 0.000000
  1939. X252 10008.000000 2.500000 0.000000
  1940. X253 10258.000000 -2.500000 0.000000
  1941. X254 10383.000000 -2.500000 0.000000
  1942. X255 10383.000000 2.500000 0.000000
  1943. X256 10258.000000 2.500000 0.000000
  1944. X257 10508.000000 -2.500000 0.000000
  1945. X258 10633.000000 -2.500000 0.000000
  1946. X259 10633.000000 2.500000 0.000000
  1947. X260 10508.000000 2.500000 0.000000
  1948. X261 10758.000000 -2.500000 0.000000
  1949. X262 10883.000000 -2.500000 0.000000
  1950. X263 10883.000000 2.500000 0.000000
  1951. X264 10758.000000 2.500000 0.000000
  1952. X265 11008.000000 -2.500000 0.000000
  1953. X266 11133.000000 -2.500000 0.000000
  1954. X267 11133.000000 2.500000 0.000000
  1955. X268 11008.000000 2.500000 0.000000
  1956. X269 11258.000000 -2.500000 0.000000
  1957. X270 11383.000000 -2.500000 0.000000
  1958. X271 11383.000000 2.500000 0.000000
  1959. X272 11258.000000 2.500000 0.000000
  1960. X273 11508.000000 -2.500000 0.000000
  1961. X274 11633.000000 -2.500000 0.000000
  1962. X275 11633.000000 2.500000 0.000000
  1963. X276 11508.000000 2.500000 0.000000
  1964. X277 11758.000000 -2.500000 0.000000
  1965. X278 11883.000000 -2.500000 0.000000
  1966. X279 11883.000000 2.500000 0.000000
  1967. X280 11758.000000 2.500000 0.000000
  1968. X#b7b19f 4  1 2 3 4
  1969. Xwhite 4  5 6 7 8
  1970. Xwhite 4  9 10 11 12
  1971. Xwhite 4  13 14 15 16
  1972. Xwhite 4  17 18 19 20
  1973. Xwhite 4  21 22 23 24
  1974. Xwhite 4  25 26 27 28
  1975. Xwhite 4  29 30 31 32
  1976. Xwhite 4  33 34 35 36
  1977. Xwhite 4  37 38 39 40
  1978. Xwhite 4  41 42 43 44
  1979. Xwhite 4  45 46 47 48
  1980. Xwhite 4  49 50 51 52
  1981. Xwhite 4  53 54 55 56
  1982. Xwhite 4  57 58 59 60
  1983. Xwhite 4  61 62 63 64
  1984. Xwhite 4  65 66 67 68
  1985. Xwhite 4  69 70 71 72
  1986. Xwhite 4  73 74 75 76
  1987. Xwhite 4  77 78 79 80
  1988. Xwhite 4  81 82 83 84
  1989. Xwhite 4  85 86 87 88
  1990. Xwhite 4  89 90 91 92
  1991. Xwhite 4  93 94 95 96
  1992. Xwhite 4  97 98 99 100
  1993. Xwhite 4  101 102 103 104
  1994. Xwhite 4  105 106 107 108
  1995. Xwhite 4  109 110 111 112
  1996. Xwhite 4  113 114 115 116
  1997. Xwhite 4  117 118 119 120
  1998. Xwhite 4  121 122 123 124
  1999. Xwhite 4  125 126 127 128
  2000. Xwhite 4  129 130 131 132
  2001. Xwhite 4  133 134 135 136
  2002. Xwhite 4  137 138 139 140
  2003. Xwhite 4  141 142 143 144
  2004. Xwhite 4  145 146 147 148
  2005. Xwhite 4  149 150 151 152
  2006. Xwhite 4  153 154 155 156
  2007. Xwhite 4  157 158 159 160
  2008. Xwhite 4  161 162 163 164
  2009. Xwhite 4  165 166 167 168
  2010. Xwhite 4  169 170 171 172
  2011. Xwhite 4  173 174 175 176
  2012. Xwhite 4  177 178 179 180
  2013. Xwhite 4  181 182 183 184
  2014. Xwhite 4  185 186 187 188
  2015. Xwhite 4  189 190 191 192
  2016. Xwhite 4  193 194 195 196
  2017. Xwhite 4  197 198 199 200
  2018. Xwhite 4  201 202 203 204
  2019. Xwhite 4  205 206 207 208
  2020. Xwhite 4  209 210 211 212
  2021. Xwhite 4  213 214 215 216
  2022. Xwhite 4  217 218 219 220
  2023. Xwhite 4  221 222 223 224
  2024. Xwhite 4  225 226 227 228
  2025. Xwhite 4  229 230 231 232
  2026. Xwhite 4  233 234 235 236
  2027. Xwhite 4  237 238 239 240
  2028. Xwhite 4  241 242 243 244
  2029. Xwhite 4  245 246 247 248
  2030. Xwhite 4  249 250 251 252
  2031. Xwhite 4  253 254 255 256
  2032. Xwhite 4  257 258 259 260
  2033. Xwhite 4  261 262 263 264
  2034. Xwhite 4  265 266 267 268
  2035. Xwhite 4  269 270 271 272
  2036. Xwhite 4  273 274 275 276
  2037. Xwhite 4  277 278 279 280
  2038. *-*-END-of-./fsim/rwy.old-*-*
  2039. -- 
  2040. Riley Rainey            Internet: riley@mips.com
  2041. MIPS Computer Systems        Phone:    +1 214 770-7979
  2042. Dallas, Texas
  2043.  
  2044. dan
  2045. ----------------------------------------------------
  2046. O'Reilly && Associates   argv@sun.com / argv@ora.com
  2047. Opinions expressed reflect those of the author only.
  2048.